package common

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"unsafe"

	"github.com/spf13/viper"
)

type AccessToken struct {
	AccessToken string `json:"access_token"`
	ExpiresIn   int    `json:"expires_in"`
}

type Phone struct {
	Errcode   string `json:"errcode"`
	Errmsg    int    `json:"errmsg"`
	PhoneInfo PhoneInfo
}

type PhoneInfo struct {
	PhoneNumber string `json:"phoneNumber"`
}

func http_get(url string) string {
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	resp, err := client.Get(url)
	if err != nil {
		return err.Error()
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		return err.Error()
	}
	return string(body)
}

func http_post(url string, code string) string {
	query := make(map[string]string)
	query["code"] = code
	bytesData, err := json.Marshal(query)
	if err != nil {
		return err.Error()
	}
	reader := bytes.NewReader(bytesData)
	request, err := http.NewRequest("POST", url, reader)
	//defer request.Body.Close() //程序在使用完回复后必须关闭回复的主体
	if err != nil {
		return err.Error()
	}
	request.Header.Set("Content-Type", "application/json;charset=UTF-8")
	//必须设定该参数,POST参数才能正常提交，意思是以json串提交数据

	client := http.Client{}
	resp, err := client.Do(request) //Do 方法发送请求，返回 HTTP 回复
	if err != nil {
		return err.Error()
	}

	respBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err.Error()
	}

	//byte数组直接转成string，优化内存
	str := (*string)(unsafe.Pointer(&respBytes))

	return string(*str)
}

func GetOpenid(code string) string {
	url := "https://api.weixin.qq.com/sns/jscode2session?appid=" + viper.GetString("wx.appId") + "&secret=" + viper.GetString("wx.secret") + "&js_code=" + code + "&grant_type=authorization_code"
	data := http_get(url)
	var tmpresult map[string]interface{}
	json.Unmarshal([]byte(data), &tmpresult)
	return tmpresult["openid"].(string)
}

func GetAccessToken(code string) string {
	url := "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + viper.GetString("wx.appId") + "&secret=" + viper.GetString("wx.secret")
	res := http_get(url)
	var data AccessToken
	if err := json.Unmarshal([]byte(res), &data); err == nil {
		access_token := data.AccessToken
		return access_token
	} else {
		fmt.Println(err)
		return err.Error()
	}

}

func GetPhone(access_token string, code string) string {
	url := "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + access_token + "&"
	res := http_post(url, code)
	var tmpresult map[string]interface{}
	json.Unmarshal([]byte(res), &tmpresult)
	data := tmpresult["phone_info"].(map[string]interface{})
	return data["phoneNumber"].(string)

}
